package com.ch.base.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

public class FileUtils {
	/**
	 * 寫入文字檔(編碼為預設的iso-8859-1)
	 * @param text		將整個String寫入指定的檔案
	 * @param savePath	請直接輸入專案底下之路徑
	 * @param filename	檔案名稱
	 * @param format	寫入檔案的編碼格式
	 * @param append	true：將此次寫檔串在原本檔案最後面；false：將此次寫檔蓋掉原本的文字檔內容
	 * @return			true：寫檔成功；false：寫檔失敗
	 */
	public static boolean writeText(String text, String savePath, String filename, String format, boolean append){
		if(text.equals("")){
			return false;
		}
		String root = ServletActionContext.getRequest().getRealPath(savePath);
		if(!new File(root).exists()){
			FileUtils.mkDir(savePath);
		}   
		File file = new File(root + "/" + filename);//建立檔案，準備寫檔
		try{
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file,append),format));
			bw.write(text);
			bw.close();
		}catch(IOException e){
			e.printStackTrace();
			System.out.println(savePath+filename + "寫檔發生錯誤");
			return false;
		}
		return true;
	}


	/**
	 * 寫入檔案使用utf8格式寫檔，並且復蓋原本檔案內容
	 * @param text		將整個String寫入指定的檔案
	 * @param savePath	請直接輸入專案底下之路徑
	 * @param filename	檔案名稱
	 * @return			true：寫檔成功；false：寫檔失敗
	 */
	public static boolean writeTextByUtf8(String text, String savePath, String filename){
		return writeText(text, savePath, filename, "utf8", false);
	}

	/**
	 * 寫入檔案使用big5格式寫檔，並且復蓋原本檔案內容
	 * @param text		將整個String寫入指定的檔案
	 * @param savePath	請直接輸入專案底下之路徑
	 * @param filename	檔案名稱
	 * @return			true：寫檔成功；false：寫檔失敗
	 */
	public static boolean writeTextByBig5(String text, String savePath, String filename){
		return writeText(text, savePath, filename, "big5", false);
	}

	/**
	 * 寫入檔案使用utf8格式寫檔，串在原本檔案內容後面
	 * @param text		將整個String寫入指定的檔案
	 * @param savePath	請直接輸入專案底下之路徑
	 * @param filename	檔案名稱
	 * @return			true：寫檔成功；false：寫檔失敗
	 */
	public static boolean writeTextByUtf8Apend(String text, String savePath, String filename){
		return writeText(text, savePath, filename, "utf8", true);
	}

	/**
	 * 寫入檔案使用big5格式寫檔，串在原本檔案內容後面
	 * @param text		將整個String寫入指定的檔案
	 * @param savePath	請直接輸入專案底下之路徑
	 * @param filename	檔案名稱
	 * @return			true：寫檔成功；false：寫檔失敗
	 */
	public static boolean writeTextByBig5Apend(String text, String savePath, String filename){
		return writeText(text, savePath, filename, "big5", true);
	}

	/**
	 * 檢查檔案是否存在
	 * @param savePath	可用相對路徑或絕對路徑
	 * @param filename	檔案名稱
	 * @return 			true：檔案已存在；false：檔案不存在
	 */
	public static boolean exists(String savePath, String filename){
		HttpServletRequest request;
		request = ServletActionContext.getRequest();

		String path = request.getRealPath(savePath);
		return new File(path+filename).exists();
	}

	/**
	 * 下載網頁上的檔案
	 * @param urlPath	下載網址
	 * @param savePath	儲存檔案路徑(請直接輸入專案底下之路徑)
	 * @param filename	欲儲存之檔案名稱
	 * @return			檔名 or error
	 */
	public String loadURLFile(String urlPath, String savePath, String filename){
		String msg = "";
		try{
			URL url = new URL(urlPath);
			String name = url.getFile();
			String tmpName = name.substring(name.lastIndexOf("."), name.length());//取得副檔名
			msg = filename + tmpName;	//新取的檔名 + 副檔名
			BufferedInputStream bis = new BufferedInputStream(url.openStream());
			byte[] b = new byte[1024];	//一次取得 1024 個 bytes
			String root = ServletActionContext.getRequest().getRealPath(savePath);
			FileOutputStream fos=new FileOutputStream(root + "/" + msg);
			int len;
			while((len = bis.read(b,0,b.length))!=-1){
				fos.write(b,0,len);
			}
			bis.close();
			fos.close();
		}catch(IOException e){
			e.printStackTrace();
			System.out.println("讀取檔案寫入時發生錯誤");
			msg = "error";
		}
		return msg;
	}

	/**
	 * 取得整個網頁的html，使用BIG5格式編碼
	 * @param urlPath 	網址,例如:http://tw.yahoo.com/
	 * @return			整個網頁的html
	 */
	public String getHTML_BIG5(String urlPath){
		return getHTML(urlPath, "Big5");
	}

	/**
	 * 取得整個網頁的html，使用utf8格式編碼
	 * @param urlPath	網址
	 * @return			整個網頁的html
	 */
	public String getHTML_UTF8(String urlPath){
		return getHTML(urlPath, "utf8");
	}

	/**
	 * 取得整個網頁的html
	 * @param urlPath	網址，例如:http://tw.yahoo.com/
	 * @param fmt		網頁編碼格式(utf8,big5)
	 * @return			整個網頁的html
	 */
	public String getHTML(String urlPath, String fmt){
		StringBuffer total = new StringBuffer();
		try{
			URL url = new URL(urlPath); 
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.connect(); 
			InputStream inStream = connection.getInputStream(); 
			BufferedReader reader = new BufferedReader(new InputStreamReader(inStream,fmt)); 
			String line=""; 
			while ((line = reader.readLine()) !=null ){ 
				total.append(line + "\n");
			} 
			//System.out.println("檔案："+total);
		}catch(IOException e){
			e.printStackTrace();
			System.out.println("取得網頁html時發生錯誤");
		}
		return total.toString();
	}

	/**
	 * 尋找檔名開頭有XXX的檔案數量
	 * @param path	請直接輸入專案底下之路徑
	 * @param filename	搜尋檔案之名稱
	 * @return			檔案數量
	 */
	public static int getFileNum(String path, final String filename){
		HttpServletRequest request;
		request = ServletActionContext.getRequest();
		
		String root = request.getRealPath(path);
		int result = 0;
		File file = new File(root);
		FilenameFilter filter = new FilenameFilter() { 
			public boolean accept(File fileDir, String name) {
				return (name.startsWith(filename));  
			} 
		};
		File[] files = file.listFiles(filter);
		if(files!=null && files.length>0){
			result = files.length;
		}
		return result;
	}

	/**
	 * 建立資料夾(可建多層資料夾)
	 * @param path	最後一層的資料夾(請直接輸入專案底下之路徑)
	 */
	public static void mkDir(String path){
		HttpServletRequest request;
		request = ServletActionContext.getRequest();

		String root = request.getRealPath(path);
		if(!new File(root).exists()){
			String [] pathAry = {root};
			//pathAry = path.split("[/]");
			pathAry = root.split("[/]|\\\\");
			StringBuffer list = new StringBuffer();
			for(int i = 0; i < pathAry.length; i++){
				if(!pathAry[i].equals("")){
					list.append(pathAry[i] + "/");
					File dir = new File(list.toString());
					if (!dir.isDirectory()){
						dir.mkdir();
					}
				}
			}
		}
	}

	public static void upload(File uploadFile, String savePath, String saveFilename){
		if(FileUtils.exists(savePath, "")){
			FileUtils.mkDir(savePath);
		}

		HttpServletRequest request;
		request = ServletActionContext.getRequest();
		
		String path = request.getRealPath(savePath);

		try {
			File target = new File(path, saveFilename);
			org.apache.commons.io.FileUtils.copyFile(uploadFile, target);
		}catch(FileNotFoundException e){    
			e.printStackTrace();   
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 刪除檔案
	 * @param savePath		可用相對路徑或絕對路徑
	 * @param saveFilename	檔案名稱
	 */
	public static void delete(String savePath, String saveFilename) throws FileNotFoundException {
		HttpServletRequest request;
		request = ServletActionContext.getRequest();

		File file = new File(request.getRealPath(savePath)+"/"+saveFilename);
		file.delete();

	}

	public static void copy(String orgPath, String orgFilename, String newPath, String newFilename, boolean deleteOrgFile) throws Exception {
		if(FileUtils.exists(newPath, "")){
			FileUtils.mkDir(newPath);
		}

		HttpServletRequest request;
		request = ServletActionContext.getRequest();

		File orgFile = new File(request.getRealPath(orgPath)+"/"+orgFilename);
		FileUtils.upload(orgFile, newPath, newFilename);

		if(deleteOrgFile){
			FileUtils.delete(orgPath, orgFilename);
		}
	}
}

